package com.ruoyi.mf178.utils;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.mf178.domain.Mf178Request;
import lombok.SneakyThrows;
import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.lang.reflect.Field;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;


public class Mf178Utils {
    public static final Logger log = LoggerFactory.getLogger(Mf178Utils.class);

    public static String sign(String appSecret, Map<String, String> data) {
        TreeMap<String, String> params = new TreeMap<String, String>(data);

        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> item : params.entrySet()) {
            if (item.getKey().equals("sign"))
                continue;
            sb.append(item.getKey()).append(item.getValue());
        }
        sb.append(appSecret);
        log.info("签名前字符串---" + sb);
        String result = Md5Utils.hash(sb.toString());
        log.info("签名结果---" + result);
        return result;
    }

    public static Map<String, String> JavaToMapString(Object entity) {
        Map<String, String> map = new HashMap<>();
        Class<?> clazz = entity.getClass();
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            field.setAccessible(true); // 确保可以访问私有字段
            try {
                map.put(field.getName(), String.valueOf(field.get(entity)));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    public static String mf178DoPostJson(String url, String appKey, String appSecret, String dataJsonString) {
        Mf178Request request = new Mf178Request();
        request.setApp_key(appKey);
        request.setTimestamp(System.currentTimeMillis() / 1000L);
        request.setData(dataJsonString);
        request.setSign(Mf178Utils.sign(appSecret, Mf178Utils.JavaToMapString(request)));
        String result = Mf178Utils.doPostJson(url, null, JSONObject.toJSONString(request));
        return result;
    }

    public static String doPostJson(String url, Map<String, String> header, String json) {
        log.info("doPostJson - " + url);
        log.info("header - " + ((header != null) ? JSONObject.toJSONString(header) : null));
        log.info("json - " + json);
        HttpClientBuilder httpClientBuilder = createSSLClientDefault();
        HttpHost httpHost = null;
        CloseableHttpClient httpclient = httpClientBuilder.build();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            HttpPost httpPost = new HttpPost(url);
            RequestConfig.Builder requestBuilder = RequestConfig.custom().setConnectTimeout(10000)
                    .setSocketTimeout(10000);
            if (httpHost != null) {
                requestBuilder.setProxy(httpHost);
            }
            RequestConfig requestConfig = requestBuilder.build();
            httpPost.setConfig(requestConfig);
            StringEntity entity = new StringEntity(json, "UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            if (header != null && !header.isEmpty()) {
                for (String key : header.keySet()) {
                    httpPost.addHeader(key, header.get(key));
                }
            }
            response = httpclient.execute(httpPost);
            if (response.getEntity() != null) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        log.info("result - " + resultString);
        return resultString;
    }


    public static String doPostFormUrlEncoded(String url, Map<String, String> header, Map<String, String> params) {
        log.info("doPostFormUrlEncoded - " + url);
        log.info("header - " + ((header != null) ? JSONObject.toJSONString(header) : null));
        log.info("params - " + ((params != null) ? JSONObject.toJSONString(params) : null));

        HttpClientBuilder httpClientBuilder = createSSLClientDefault();
        CloseableHttpClient httpclient = httpClientBuilder.build();
        CloseableHttpResponse response = null;
        String resultString = "";

        try {
            HttpPost httpPost = new HttpPost(url);
            RequestConfig.Builder requestBuilder = RequestConfig.custom()
                    .setConnectTimeout(10000)
                    .setSocketTimeout(10000);
            RequestConfig requestConfig = requestBuilder.build();
            httpPost.setConfig(requestConfig);

            // 设置请求头
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            if (header != null && !header.isEmpty()) {
                for (String key : header.keySet()) {
                    httpPost.addHeader(key, header.get(key));
                }
            }

            // 构建请求体
            List<NameValuePair> nvps = new ArrayList<>();
            if (params != null && !params.isEmpty()) {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                }
            }
            httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));

            response = httpclient.execute(httpPost);
            if (response.getEntity() != null) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        log.info("result - " + resultString);
        return resultString;
    }

    @SneakyThrows
    public static HttpClientBuilder createSSLClientDefault() {
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            //信任所有
            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                return true;
            }
        }).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
        return HttpClients.custom().setSSLSocketFactory(sslsf);
    }
}
